<template>
  <!-- 顶部导航栏的通知铃铛组件 -->
  <el-popover
    v-model:visible="popoverVisible"
    placement="bottom"
    :width="400"
    trigger="click"
    @show="handlePopoverShow"
  >
    <template #reference>
      <div class="notification-bell">
        <el-badge :value="unreadCount" :hidden="unreadCount === 0" :max="99">
          <el-icon :size="20"><Bell /></el-icon>
        </el-badge>
      </div>
    </template>

    <!-- 弹出框内容 -->
    <div class="notification-popover">
      <!-- 头部 -->
      <div class="popover-header">
        <span class="title">通知</span>
        <el-button type="text" size="small" @click="handleMarkAllAsRead">
          全部已读
        </el-button>
      </div>

      <!-- 通知列表 -->
      <div v-loading="loading" class="notification-list">
        <div
          v-for="notification in latestNotifications"
          :key="notification.id"
          class="notification-item"
          :class="{ unread: !notification.isRead }"
          @click="handleNotificationClick(notification)"
        >
          <el-avatar
            :src="formatAvatarUrl(notification.sender?.avatar)"
            size="small"
          >
            {{ notification.sender?.nickName?.charAt(0) }}
          </el-avatar>
          <div class="notification-content">
            <div class="notification-text">
              <span class="sender-name">{{
                notification.sender?.nickName
              }}</span>
              <span class="action-text">{{
                notification.actionText || notification.typeName
              }}</span>
            </div>
            <!-- 显示文章标题或评论内容 -->
            <div
              v-if="notification.articleInfo?.title"
              class="notification-target"
            >
              {{ notification.articleInfo.title }}
            </div>
            <div
              v-else-if="notification.commentDetail?.content"
              class="notification-description"
            >
              {{ notification.commentDetail.content }}
            </div>
            <div class="notification-time">
              {{ formatTime(notification.createTime) }}
            </div>
          </div>
          <div v-if="!notification.isRead" class="unread-dot" />
        </div>

        <!-- 空状态 -->
        <el-empty
          v-if="!loading && latestNotifications.length === 0"
          description="暂无通知"
          :image-size="80"
        />
      </div>

      <!-- 底部 -->
      <div class="popover-footer">
        <el-button type="text" @click="goToNotificationCenter">
          查看全部通知
        </el-button>
      </div>
    </div>
  </el-popover>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, onUnmounted } from "vue";
import { useRouter } from "vue-router";
import { ElMessage } from "element-plus";
import { Bell } from "@element-plus/icons-vue";
import {
  markAllNotificationsAsReadApi,
  markNotificationAsReadApi,
  type NotificationDetail
} from "@/api/notification";
import { notificationService } from "@/services/notificationService";

const router = useRouter();
const loading = ref(false);
const popoverVisible = ref(false);

// 使用单例服务的响应式数据
const statsRef = notificationService.getStatsRef();
const latestNotifications = notificationService.getLatestNotificationsRef();

// 计算未读数量
const unreadCount = computed(() => {
  return statsRef.value?.totalUnreadCount || 0;
});

// 格式化头像URL
const formatAvatarUrl = (url: string): string => {
  if (!url) return "";

  // 如果已经是完整URL，直接返回
  if (url.startsWith("http://") || url.startsWith("https://")) {
    return url;
  }

  // 如果是相对路径，添加基础URL
  const baseURL = import.meta.env.DEV
    ? "http://localhost:8081"
    : "http://localhost:8081";
  return baseURL + url;
};

// 加载最新通知
const loadLatestNotifications = async () => {
  loading.value = true;
  try {
    await notificationService.loadLatestNotifications(10);
  } finally {
    loading.value = false;
  }
};

// 弹出框显示时刷新数据
const handlePopoverShow = () => {
  loadLatestNotifications();
};

// 点击通知项
const handleNotificationClick = async (notification: NotificationDetail) => {
  // 标记为已读
  if (!notification.isRead) {
    try {
      await markNotificationAsReadApi(notification.id);
      notification.isRead = 1;
      notificationService.decreaseUnreadCount(1);
    } catch (error) {
      console.error("标记已读失败", error);
    }
  }

  // 关闭弹出框
  popoverVisible.value = false;

  // 跳转到目标页面
  if (notification.target?.url) {
    router.push(notification.target.url);
  }
};

// 全部标记为已读
const handleMarkAllAsRead = async () => {
  try {
    const response = await markAllNotificationsAsReadApi();
    if (response.code === 200) {
      ElMessage.success("已全部标记为已读");
      latestNotifications.value.forEach(n => (n.isRead = 1));
      notificationService.clearUnreadCount();
    }
  } catch (error) {
    ElMessage.error("操作失败");
    console.error(error);
  }
};

// 跳转到通知中心
const goToNotificationCenter = () => {
  // 关闭弹出框
  popoverVisible.value = false;
  // 跳转到消息中心
  router.push("/user/messages");
};

// 格式化时间
const formatTime = (time: string) => {
  if (!time) return "";

  const now = new Date();
  const noticeTime = new Date(time);
  const diff = now.getTime() - noticeTime.getTime();

  const minutes = Math.floor(diff / 60000);
  const hours = Math.floor(diff / 3600000);
  const days = Math.floor(diff / 86400000);

  if (minutes < 1) return "刚刚";
  if (minutes < 60) return `${minutes}分钟前`;
  if (hours < 24) return `${hours}小时前`;
  if (days < 7) return `${days}天前`;

  return time.split(" ")[0]; // 返回日期部分
};

// 初始化
onMounted(() => {
  // 🔑 优化: 不再主动调用 loadStats()，依赖 App.vue 的统一初始化
  // 通过单例服务的 statsRef 响应式数据自动更新界面
  console.log("🔔 UserNotification 组件已加载，使用单例服务的统计数据");
});

// 组件卸载时清理
onUnmounted(() => {
  // 单例服务会统一管理
});

// 暴露刷新方法供外部调用
defineExpose({
  refresh: () => {
    loadLatestNotifications();
  }
});
</script>

<style scoped lang="scss">
.notification-bell {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  cursor: pointer;
  border-radius: 50%;
  transition: all 0.3s ease;

  &:hover {
    background: #f2f3f5;
  }

  :deep(.el-badge) {
    display: flex;
    align-items: center;
    justify-content: center;
  }

  :deep(.el-icon) {
    color: #4e5969;
    transition: color 0.3s;

    &:hover {
      color: #1d2129;
    }
  }
}

.notification-popover {
  .popover-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding-bottom: 12px;
    border-bottom: 1px solid #e8e8e8;

    .title {
      font-size: 16px;
      font-weight: 600;
      color: #303133;
    }
  }

  .notification-list {
    max-height: 400px;
    margin: 12px 0;
    overflow-y: auto;
  }

  .notification-item {
    position: relative;
    display: flex;
    align-items: flex-start;
    padding: 12px;
    cursor: pointer;
    border-radius: 4px;
    transition: background 0.3s;

    &:hover {
      background: #f5f7fa;
    }

    &.unread {
      background: #f0f9ff;
    }

    .el-avatar {
      flex-shrink: 0;
      margin-right: 12px;
    }

    .notification-content {
      flex: 1;
      min-width: 0;

      .notification-text {
        margin-bottom: 4px;

        .sender-name {
          margin-right: 4px;
          font-weight: 500;
          color: #303133;
        }

        .action-text {
          font-size: 14px;
          color: #606266;
        }
      }

      .notification-description {
        display: -webkit-box;
        margin-bottom: 4px;
        overflow: hidden;
        text-overflow: ellipsis;
        -webkit-line-clamp: 2;
        font-size: 13px;
        line-height: 1.5;
        color: #606266;
        -webkit-box-orient: vertical;
      }

      .notification-target {
        margin-bottom: 4px;
        overflow: hidden;
        text-overflow: ellipsis;
        font-size: 13px;
        color: #409eff;
        white-space: nowrap;
      }

      .notification-time {
        font-size: 12px;
        color: #c0c4cc;
      }
    }

    .unread-dot {
      position: absolute;
      top: 16px;
      right: 12px;
      width: 8px;
      height: 8px;
      background: #409eff;
      border-radius: 50%;
    }
  }

  .popover-footer {
    padding-top: 12px;
    text-align: center;
    border-top: 1px solid #e8e8e8;
  }
}
</style>
